<template>
  <div class="role">

    <div class="btns">
      <el-button type="primary" @click="dialogVisible =true"> 添加</el-button>
      <el-button type="primary" @click="drawerVisble =true"> 打开抽屉</el-button>

    </div>

    <!-- 表格 -->
    <!-- default-expand-all -->
    <el-table
      :data="roles"
      style="width: 100%; margin-bottom: 20px"
      row-key="id"
      border 
      default-expand-all
    >
      <template #empty>
        <el-empty description="暂无数据" />
      </template>
      <el-table-column type="index"  label="#" />
      <el-table-column prop="name" label="角色名称" />
      <el-table-column prop="description" label="角色描述"/>
      <el-table-column prop="icon" label="操作">
        <template #default="{row}">
          <el-button type="primary" size="small" @click="handleSReave(row)">授权</el-button>
          <el-button type="primary" size="small" @click="handleEdit(row)">修改</el-button>
          <el-button type="danger" size="small" @click="handleDelete(row)">删除</el-button>
        </template>
      </el-table-column>
    </el-table>

    <!-- 添加与修改的对话框 -->
    <el-dialog v-model="dialogVisible" :title="(roleItem.id ? '修改' : '添加') + '角色'" width="500">
      <el-form :model="roles" label-width="50px" label-suffix=":">
        <el-form-item label="名称">
          <el-input v-model="roleItem.name" placeholder="请输入角色名称"/>
        </el-form-item>

        <el-form-item label="描述">
          <el-input 
          type="textarea"
          :rows="4"
          v-model="roleItem.description" 
          placeholder="请输入描述信息"/>
        </el-form-item>
      </el-form>
      <template #footer>
        <div class="dialog-footer">
          <el-button @click="dialogVisible = false">取消</el-button>
          <el-button type="primary" @click="handleSave"> 
          {{roleItem.id ? '修改' : '添加'}}  
          </el-button>
        </div>
      </template>
    </el-dialog>

    <!-- 授权抽屉 -->
  <el-drawer
  v-model="drawerVisble"
    title="为角色授权"
    direction="rtl"
  
  >
    <div class="demo-drawer__content">
      <!-- 树形控件,用于显示菜单权限列表 -->
          <el-tree  
        style="max-width: 600px"
        show-checkbox
        :data="menus"
        node-key="id"
        :props="{label:'name'}"
        ref="menuRef"
        default-expand-all

      />
      <div style="text-align:right">
        <el-button type="danger" size="small" @click="handleCheckAll">全选</el-button>
        <el-button size="small" @click="drawerVisble = false">取消</el-button>
        <el-button type="primary" size="small" @click="handlesavePression">保存</el-button>
      </div>
    </div>
  </el-drawer>

  </div>
</template>

<script setup lang="ts">
import {ref,watch}  from "vue"
import {getAllRoles,addRole,editRole,delRole} from "@/API/role"
import { getAllMenuPermissions } from "@/API/menu-permisssion";
import {  ElMessageBox } from "element-plus";
import {transData,getLeafNodeKeys } from "@/utils/index"


// 对话框的显示与隐藏
const dialogVisible = ref<boolean>(false)
// 抽体显影状态
const drawerVisble = ref<boolean>(false)

// 所有角色数据
const roles = ref<IRole[]>([])


// 表单中的角色数据
const roleItem = ref<IRole>({
    id:"",
    name:"",
    description:"",

})




/**
 * 查询是所有角色数据
 */
const loadRoles = async () =>{
  const res = await getAllRoles()
  roles.value = res.list
  console.log(roles.value)
}
loadRoles()


// 监视对话框关闭时，重置表单中的数据
watch(dialogVisible,(newValue)=>{
  if(!newValue){
    roleItem.value = {
      id:"",
      name:"",
      description:"",
    }
  }
})


// 点击编辑按钮，打开对话框，回显表单数据
const handleEdit = (rowL:IRole)=>{
  // 显示对话框
  dialogVisible.value = true
  // 回显表单数据
  roleItem.value = {...rowL}

}

/***
 * 保存表单中提交的角色信息：添加或修改
 */
const handleSave =async () =>{
  console.log("保存角色信息")
  // 添加
  if(!roleItem.value.id){
    await addRole(roleItem.value)
  }else{
    // 修改
   await editRole(roleItem.value)
    console
  }

  // 添加成功
  dialogVisible.value= false 
  // 重新渲染角色列表
  loadRoles()
}



/**
 * 删除角色，需要进行二次确认
 */
const handleDelete = async(row:IRole) =>{
  try {
   const result =  await ElMessageBox.confirm( '此操作将永久删除该菜单，是否继续？', '提示', {
      confirmButtonText: '确定',
      cancelButtonText: '取消',
      type: 'warning',
    })
    //如果用户确认删除，就发送网络请求，删除数据
    if( result  ===  "confirm"){
      await delRole(row.id)
      // 重新加载菜单权限数据
      loadRoles()
    }
}catch(error){
 console.log("点击了取消...",error)
}

}

// 所有菜单数据
const menus = ref<IPermission[]>([])

//菜单权限树形控件的引用
const menuRef = ref<any>()

// 待授权的角色数据
const revokRole= ref<IRole>()

/***
 * 加载所有的菜单权限数据
 */
const loadMenus = async ()=>{
  // 查询所有的菜单权限数据
  const res = await getAllMenuPermissions()
  // console.log(res.list)
  // menus.value = res.list
  // 将菜单权限树形结构
    menus.value = transData(res.list)
    console.log(menus.value)
}


/****
 * 点击授权按钮，显示授权抽屉
 * handleSReave(row)
 */
const handleSReave =async (row:IRole) =>{
  drawerVisble.value = true
  // 设置带授权的角色信息
  revokRole.value = {...row}
  // 判断是都有菜单权限数据，没有则加载
  if(menus.value.length === 0 ){
    await loadMenus()
  }

  // 获得当前待授权角色的已有权限，并勾选
  console.log(row)
  // row.permissions 中既有半选状态的权限，也有全选状态的权限
  // 半选状态的权限，需要单独处理，不能直接调用 setelectedKeys'处理
  // menuRef.value.setCheckedKeys(row.permissions)
  // 需要找出 row.permissions数组中所有的叶子节点权限id
 const leaf = getLeafNodeKeys(menus.value,row.permissions as string)

 menuRef.value.setCheckedKeys(leaf)
  
  

}
/** 
 * 保存角色授权数据
 */
const handlesavePression = async ()=>{
// 打印组件中的使用了ref的数据

    // 获取在树形控件中勾选与半选的节点数据
    console.log("menuRef.value:",menuRef.value)
    const checkedkeys = menuRef.value.getCheckedKeys()
    console.log("checkedkeys:",checkedkeys)
    const halfCheckedKeys = menuRef.value.getHalfCheckedKeys()
    console.log("halfCheckedKeys:",halfCheckedKeys)
    // 合并权限的列表 keys
    const permission = [...checkedkeys,...halfCheckedKeys]
    console.log(permission)
    if(revokRole.value){
      revokRole.value.permissions = permission
       // 调用api 方法实现，角色数据修改
       await  editRole(revokRole.value)

      // 重新加载角色列表数据
      loadRoles()
  
    }
    // 关闭抽屉
    drawerVisble.value = false
   
}

/***
 *  全选所有权限
 */
 const handleCheckAll = ()=>{
  menuRef.value.setCheckedNodes(menus.value)

 }


</script>

<style lang="less" scoped>

.role{
  padding: 12px;

  .btns{
    margin-bottom:12px;
  }
}

</style>
